﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using ControleRepresentanteSync.Application.Pedido;
using ControleRepresentanteSync.Application.Setup;
using ControleRepresentanteSync.Application.Wizard;
using ControleRepresentanteSync.Logic;

namespace ControleRepresentanteSync.Application
{
    class MainWindowPresenter : PresenterBase<IMainWindowViewModel>
    {
        private readonly IViewModelFactory m_ViewModelFactory;
        private readonly IUserInterfaceService m_UserInterfaceService;
        private readonly ConfigurationInfo m_ConfigurationInfo;
        private readonly ISyncServiceProvider m_SyncServiceProvider;
        private readonly ISectionItem m_SetupSection;
        private readonly ISectionItem m_PedidoSection;
        private readonly IContractsProvider m_ContractsProvider;

        public MainWindowPresenter(IMainWindowViewModel mainWindowViewModel, IViewModelFactory viewModelFactory, IUserInterfaceService userInterfaceService)
            : base(mainWindowViewModel)
        {
            m_ViewModelFactory = viewModelFactory;
            m_UserInterfaceService = userInterfaceService;

            m_ConfigurationInfo = new ConfigurationInfo();
            if (!m_ConfigurationInfo.IsValid)
            {
                RunSetupWizard(true);
            }

            m_SetupSection = viewModelFactory.CreateViewModel<ISectionItem>();
            m_SetupSection.Title = "Configurações";
            m_SetupSection.Open += SetupOpen;
            ViewModel.AddSection(m_SetupSection);

            ViewModel.AddSection(viewModelFactory.CreateViewModel<IDividerSectionItem>());

            m_PedidoSection = viewModelFactory.CreateViewModel<ISectionItem>();
            m_PedidoSection.Title = "Sincronizar Pedidos";
            m_PedidoSection.Open += PedidoOpen;
            ViewModel.AddSection(m_PedidoSection);

            m_ConfigurationInfo.UserSettingsChanged += ConfigurationInfoUserSettingsChanged;

            m_SyncServiceProvider = new SyncServiceProvider(m_ConfigurationInfo);

            m_ContractsProvider = new ContractsProvider(m_SyncServiceProvider);
            m_ContractsProvider.Error += ContractsProviderError;
        }

        private void ContractsProviderError(object sender, ContractsProviderErrorEventArgs e)
        {
            m_UserInterfaceService.InvokeOnUIThread(() => m_UserInterfaceService.ShowMessage(e.ErrorMessage, "Controle Representante Sync - Erro Atualizando", MessageBoxButton.OK, MessageBoxImage.Error));
        }

        private void ConfigurationInfoUserSettingsChanged(object sender, EventArgs e)
        {
            m_ContractsProvider.Refresh();
        }

        private void PedidoOpen(object sender, EventArgs e)
        {
            IEnumerable<string> pedidosFiles = m_UserInterfaceService.SelectFiles("Selecione os arquivo Excel para exportar");

            if (pedidosFiles == null)
            {
                return;
            }

            IWizardViewModel wizardViewModel = m_ViewModelFactory.CreateViewModel<IWizardViewModel>();
            IWindow window = ViewModel.CreateWizardWindow(wizardViewModel);

            WizardPageProvider pedidosPageProvider = new WizardPageProvider();
            IPedidoSyncViewModel pedidoSelectionViewModel = m_ViewModelFactory.CreateViewModel<IPedidoSyncViewModel>();
            IJolitexRetriever jolitexRetriever = new JolitexContentHandler(m_SyncServiceProvider, pedidosFiles);
            new PedidoSelectionPresenter(pedidoSelectionViewModel, m_ViewModelFactory, jolitexRetriever, pedidosPageProvider, m_ContractsProvider, m_UserInterfaceService);

            ISimpleFinishViewModel simpleFinishViewModel = m_ViewModelFactory.CreateViewModel<ISimpleFinishViewModel>();
            new SimpleFinishPresenter(simpleFinishViewModel, "Pedidos Sincronizados", "Os pedidos foram sincronizados com êxito.");

            new WizardPresenter(wizardViewModel, new CompositeWizardPageProvider(
                new WizardPageProvider(pedidoSelectionViewModel),
                pedidosPageProvider,
                new LazyWizardPageProvider(() =>
                {
                    IPedidoSyncViewModel pedidoSyncViewModel = m_ViewModelFactory.CreateViewModel<IPedidoSyncViewModel>();
                    new PedidoSyncPresenter(window, pedidoSyncViewModel, pedidoSelectionViewModel.ContentList.Contents.Where(x => x.IsChecked), m_ViewModelFactory, m_UserInterfaceService, m_SyncServiceProvider);
                    return pedidoSyncViewModel;
                }),
                new WizardPageProvider(simpleFinishViewModel)));
            m_UserInterfaceService.OpenWindow(window);
        }

        private void SetupOpen(object sender, EventArgs e)
        {
            RunSetupWizard(false);
        }

        private void RunSetupWizard(bool isFirstTime)
        {
            IWizardViewModel wizardViewModel = m_ViewModelFactory.CreateViewModel<IWizardViewModel>();
            IWindow window = ViewModel.CreateWizardWindow(wizardViewModel);

            IWelcomePageViewModel welcomePageViewModel = m_ViewModelFactory.CreateViewModel<IWelcomePageViewModel>();
            new WelcomePagePresenter(welcomePageViewModel);
            IUserPageViewModel userPageViewModel = m_ViewModelFactory.CreateViewModel<IUserPageViewModel>();
            new UserPagePresenter(window, userPageViewModel, m_ConfigurationInfo, m_UserInterfaceService);
            IStartupPageViewModel startupPageViewModel = m_ViewModelFactory.CreateViewModel<IStartupPageViewModel>();
            new StartupPagePresenter(startupPageViewModel, isFirstTime, m_UserInterfaceService);
            ISimpleFinishViewModel simpleFinishViewModel = m_ViewModelFactory.CreateViewModel<ISimpleFinishViewModel>();
            new SimpleFinishPresenter(simpleFinishViewModel, "Parabéns", "O aplicativo de sincronização foi configurado com sucesso.\n\nSe necessário, as configurações podem ser alteradas clicando no botão Configurações na janela principal do aplicativo.\n\nClique em Finalizar para fechar o assistente.");

            new WizardPresenter(wizardViewModel, new WizardPageProvider(
                welcomePageViewModel, 
                userPageViewModel, 
                startupPageViewModel,
                simpleFinishViewModel));
            m_UserInterfaceService.OpenWindow(window);
        }

        public override void Dispose()
        {
            base.Dispose();

            m_SetupSection.Open -= SetupOpen;
            m_PedidoSection.Open -= PedidoOpen;

            m_ConfigurationInfo.UserSettingsChanged -= ConfigurationInfoUserSettingsChanged;

            m_ContractsProvider.Error -= ContractsProviderError;

            ViewModel.Close();
        }
    }
}